/*
 * Copyright (c) 2015-2016, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/***** Includes *****/
#include <stdlib.h>
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>

#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>

/* Drivers */
#include <ti/drivers/rf/RF.h>
#include <ti/drivers/PIN.h>

#ifdef DEVICE_FAMILY
    #undef DEVICE_FAMILY_PATH
    #define DEVICE_FAMILY_PATH(x) <ti/devices/DEVICE_FAMILY/x>
    #include DEVICE_FAMILY_PATH(driverlib/rf_prop_mailbox.h)
#else
    #error "You must define DEVICE_FAMILY at the project level as one of cc26x0, cc26x0r2, cc13x0, etc."
#endif

/* Board Header files */
#include "Board.h"

#include "rfBleNcTx.h"
#include "RFQueue.h"
#include "smartrf_settings/smartrf_settings_ble.h"

#include <stdlib.h>

/***** Defines *****/
#define BLE_NC_TASK_STACK_SIZE 1024
#define BLE_NC_TASK_PRIORITY   2

#define BLE_BEACON_PERIOD_MS    500

#define BLE_RF_EVENT_MASK  ( RF_EventLastCmdDone | RF_EventCmdError | \
             RF_EventCmdAborted | RF_EventCmdStopped | RF_EventCmdCancelled )

/***** Prototypes *****/
static void bleNcTaskFunction(UArg arg0, UArg arg1);

/***** Variable declarations *****/
static Task_Params bleNcTaskParams;
Task_Struct bleNcTask;    /* not static so you can see in ROV */
static uint8_t bleNcTaskStack[BLE_NC_TASK_STACK_SIZE];

static RF_Object rfBleObject;
static RF_Handle rfBleHandle;

static PIN_Handle pinHandle;

static uint8_t localNameAdvertisement[] = {
        0x02, //Length of this Data section
        0x01, //<<Flags>>
        0x02, //LE General Discoverable Mode
        0x18, //Length of this Data section
        0x09, //<<Complete local name>>
        'C', 'C', '1', '3', '5', '0', ' ',
        'L', 'a', 'u', 'n', 'c', 'h',
        'p', 'a', 'd', ' ', '-', ' ', '0', 'x', '0', '0'
        };

/***** Function definitions *****/
void bleNcTask_init(PIN_Handle ledPinHandle) {

    pinHandle = ledPinHandle;

    Task_Params_init(&bleNcTaskParams);
    bleNcTaskParams.stackSize = BLE_NC_TASK_STACK_SIZE;
    bleNcTaskParams.priority = BLE_NC_TASK_PRIORITY;
    bleNcTaskParams.stack = &bleNcTaskStack;
    bleNcTaskParams.arg0 = (UInt)1000000;

    Task_construct(&bleNcTask, bleNcTaskFunction, &bleNcTaskParams, NULL);
}

static void bleNcTaskFunction(UArg arg0, UArg arg1)
{
    RF_Params rfParams;
    RF_Params_init(&rfParams);

    RF_pModeBle->rfMode = RF_MODE_MULTIPLE;

    rfBleHandle = RF_open(&rfBleObject, RF_pModeBle,
                           (RF_RadioSetup*)RF_ble_pCmdRadioSetup, NULL);

    /* Enter main task loop */
    while (1)
    {
        RF_EventMask result;
        rfc_bleAdvOutput_t advStats = {0};
        RF_ScheduleCmdParams bleSchParams;
        RF_CmdHandle cmdHdl;
        uint8_t deviceAddress[] = {0,1,2,3,4,5};
        uint8_t channel = 37;

        RF_ble_pCmdBleAdvNc->startTrigger.triggerType = TRIG_NOW;
        RF_ble_pCmdBleAdvNc->startTrigger.pastTrig = 0;
        RF_ble_pCmdBleAdvNc->startTime = 0;

        bleSchParams.priority = RF_PriorityHigh;
        //schParams.endTime = ?

        RF_ble_pCmdBleAdvNc->pParams->advLen = sizeof(localNameAdvertisement);

        RF_ble_pCmdBleAdvNc->pParams->pAdvData = (uint8_t*) localNameAdvertisement;
        RF_ble_pCmdBleAdvNc->pParams->pDeviceAddress = (uint16_t*) deviceAddress;

        //only useful for debug
        RF_ble_pCmdBleAdvNc->pOutput = &advStats;

        RF_ble_pCmdBleAdvNc->channel = channel;
        RF_ble_pCmdBleAdvNc->whitening.init = 0x40 + channel;

        PIN_setOutputValue(pinHandle, BLE_TX, 1);
        cmdHdl = RF_scheduleCmd(rfBleHandle, (RF_Op*)RF_ble_pCmdBleAdvNc, &bleSchParams, 0, 0);
        result = RF_pendCmd(rfBleHandle, cmdHdl, BLE_RF_EVENT_MASK);
        PIN_setOutputValue(pinHandle, BLE_TX, 0);

        if ((result & RF_EventLastCmdDone) && (advStats.nTxAdvInd == 1))
        {
            //PIN_setOutputValue(pinHandle, BLE_SUCCESS, 1);
        }
        else if (result & ( RF_EventCmdAborted | RF_EventCmdStopped | RF_EventCmdCancelled))
        {
            PIN_setOutputValue(pinHandle, BLE_ABORT, 1);
        }
        else
        {
            //PIN_setOutputValue(pinHandle, BLE_FAIL, 1);
        }

        PIN_setOutputValue(pinHandle, BLE_ABORT, 0);

        Task_sleep(BLE_BEACON_PERIOD_MS * 1000 / Clock_tickPeriod);
    }
}
